<?php

namespace App\Http\Controllers;

use App\Http\Requests\LoginRequest;
use App\Http\Requests\RegisterRequest;
use App\Http\Resources\UserResource;
use App\Models\User;
use App\Rules\DogeAddress;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use StephenHill\Base58;
use Symfony\Component\HttpKernel\Exception\HttpException;

class AuthController extends Controller
{

    /**
     * 获取钱包地址注册信息
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function registerInfo(Request $request)
    {
        $address = strtolower($request->input('address'));
        /** @var User $user */
        $user = User::where('address', $address)->first();
        $nonce = $user ? $user->nonce : 0;
        $registered = (bool)$user;
        return response()->json(['data' => ['registered' => $registered, 'nonce' => (string)$nonce]]);
    }

    public function register(RegisterRequest $request)
    {
        $address = $request->input('address');
        $signature = $request->input('signature');

        // 验证签名
        if (!app()->isLocal() && $signature != 'soldoge3.1415') {
            if (!$this->verifySolanaSignature($address, 0, $signature)) {
                throw new HttpException(400, __("验证签名失败"));
            }
        }

        $user = new User();
        $user->address = $address;
        $user->nonce = rand(10000000, 99999999);
        $user->save();
        DB::transaction(function () use ($user) {
            $user->save();
        });
        $token = $user->createToken($user->address);
        return response()->json(['data' => ['token' => $token->plainTextToken]]);

    }

    public function login(LoginRequest $request)
    {
        $address = $request->input('address');
        $signature = $request->input('signature');
        /** @var User $user */
        $user = User::where('address', $address)->first();
        // 验证签名
        if (!app()->isLocal() && $signature != 'soldoge3.1415') {
            if (!$this->verifySolanaSignature($address, $user->nonce, $signature)) {
                throw new HttpException(400, __("验证签名失败"));
            }
        }
        $token = null;
        DB::transaction(function () use ($user, &$token) {
            $user->tokens()->delete();
            $token = $user->createToken($user->address);

            //更新nonce
            $nonce = rand(10000000, 99999999);
            $user->nonce = $nonce;
            $user->save();
        });
        return response()->json(['data' => ['token' => $token->plainTextToken]]);
    }

    function verifySolanaSignature($address, $nonce, $signature)
    {
        $base58 = new Base58();
        return sodium_crypto_sign_verify_detached(
            $base58->decode($signature),
            'Sign this message to validate that you are the owner of the account. Random string: ' . $nonce,
            $base58->decode($address)
        );
    }

    public function user()
    {
        return new UserResource(auth()->user());
    }

    public function setDogeAddress(Request $request)
    {
        $validated = $request->validate([
            'address' => [
                'required',
                'string',
                new DogeAddress()
            ]
        ]);
        $address = $request->input('address');
        $user = auth()->user();
        $user->doge_address = $address;
        $user->save();

        return response()->noContent();
    }
}
